import React , { Component, PropTypes } from 'react';

import styles from './tableView.style.scss';

class TabView extends Component {
    constructor(){
        super();
        this.state = {
            padT:0,
            padF:0,
            animateing:false
        };
        this.cache = {};
        this.movePageX = 0;
        this.movePageY = 0;
        //动画执行事件
        this.animateTime = 500;
        //是否在执行动画
        this.animateing = false;
        this._touchStart = this._touchStart.bind(this);
        this._moveComputed = this._moveComputed.bind(this);

    }

    static propTypes = {
        renderHeader:PropTypes.func,
        renderFooter:PropTypes.func,
        page:PropTypes.number,
        //是否开启动画
        animate:PropTypes.bool,
        //回调
        onChangeBefore:PropTypes.func,
        //页面是否懒加载
        pageLazyLoad:PropTypes.bool,
    }

    static defaultProps = {
        renderHeader:()=>null,
        renderFooter:()=>null,
        page:0,
        animate:false,
        onChangeBefore:()=>{},
        pageLazyLoad:true
    }

    componentDidMount() {

        this.setState({
           padF:this.getFooterHeight()+'px',
           padT:this.getHeaderHeight()+'px'
        });

        this.props.animate && !!this.centerElement && this.bindMove();
    }

    bindMove(){
        this.centerElement.addEventListener("touchmove",this._moveComputed);
        this.centerElement.addEventListener("touchstart",this._touchStart);
    }

    unBind(){
        this.centerElement.removeEventListener("touchmove",this._moveComputed);
        this.centerElement.removeEventListener("touchstart",this._touchStart);
    }

    _getPageX( e ){
        const { touches } = e, evt = touches[0] || {};
        return evt.pageX || 0;
    }

    _getPageY ( e ) {
        const { touches } = e, evt = touches[0] || {};
        return evt.pageY || 0;
    }

    _touchStart( e ){
        this.movePageX = this._getPageX(e);
        this.movePageY = this._getPageY(e);
    }

    _moveComputed(e){
        const pageX = this._getPageX(e);
        const pageY = this._getPageY(e);
        const diffX = pageX - this.movePageX;
        const diffY = pageY - this.movePageY;

        if( Math.abs(diffY) <= 10 &&  Math.abs(diffX) >= 30 ) {
            const d = diffX > 0 ? "right":"left";
            !this.animateing && this._onChange(d);
            this.movePageX = pageX;
        }
    }

    _onChange(d){
        const { page , children , onChangeBefore } = this.props;
        const count = React.Children.count(children);
        let nextPage = d ==="left" ? page + 1: page - 1;
        if(nextPage < 0 || nextPage > count - 1 ) return;
        onChangeBefore(nextPage);
        this.animateing = true;
        this.timeouter && clearTimeout(this.timeouter);
        this.setState({ animateing:true });
        this.timeouter = setTimeout( () => {
            this.animateing = false;
            this.setState({ animateing:false });
        },this.animateTime);
    }

    componentWillUnmount(){
        this.props.animate && !!this.centerElement && this.unBind();
        this.timeouter && clearTimeout(this.timeouter);
    }

    getShowPage( page , i){

        const { pageLazyLoad } = this.props;

        if( !pageLazyLoad ) return true;

        if(this.cache[i]) {
            return true;
        } else {
            if(page === i) {
                this.cache[i] = true;
                return true;
            } else {
                this.cache[i] = false;
                return false;
            }
        }
    }

    getContrlStyle(count,page){
        return {
            width:count * 100 + '%',
            transform:`translateX(${-page/count*100}%)`,
            WebkitTransform:`translateX(${-page/count*100}%)`
        }
    }

    getHeaderHeight(){
        if(!this.header) return 0;
        return this.header.clientHeight;
    }

    getFooterHeight(){
        if(!this.footer) return 0;
        return this.footer.clientHeight;
    }

    render(){
         const {
             children,
             page,
             renderHeader,
             renderFooter,
             animate
         } = this.props;
         const count = React.Children.count(children);
         const { animateing } = this.state;
         return(
             <div
                 className={styles.tab_view_contrl}
                 ref={e=>this.contrl=e}
                 style={{
                     paddingTop:this.getHeaderHeight()+'px',
                     paddingBottom:this.getFooterHeight()+'px'
                 }}
             >
                 <div className={styles.tab_view_top} ref={e=>this.header=e}>
                     {renderHeader()}
                 </div>
                 <div
                     data-page={page}
                     className={styles.tab_view_center}
                     ref={e=>this.centerElement=e}
                 >
                     <div
                       style={this.getContrlStyle(count,page)}
                       className={`${styles.tab_contrl} ${animate ? styles.tab_contrl_animate : ''}`}
                       data-table-view-animateing={animateing}
                    >
                        { React.Children.map( children, ( element , i ) => {
                             if(!element) return null;
                             const show = this.getShowPage( page , i );
                             return show ? (
                                 <TabList
                                   i={i}
                                   key={i}
                                   count={count}
                                   element={element}
                                 /> ) : null;
                         })}
                     </div>
                 </div>
                 <div className={styles.tab_view_bottom} ref={e=>this.footer=e}>
                     {renderFooter()}
                 </div>
             </div>
         )
    }
}

class TabList extends Component {
    constructor(){
        super();
    }
    static propTypes = {
        i:PropTypes.number,
        count:PropTypes.number,
        element:PropTypes.element
    };

    static defaultProps = {
        i:0,
        count:0,
        dataSource:[],
        loadMore:()=>{},
        initLoad:()=>{},
        toBottom:100
    };

    getStyle(i,count){
        return {
            width:`${1/count*100}%`,
            transform:`translateX(${i*100}%)`,
            WebkitTransform:`translateX(${i*100}%)`
        }
    }

    render(){
        const { i ,count , element } = this.props;
        return (
            <div className={styles.tab_page} style={this.getStyle(i,count)}>
                {element}
            </div>
        )
    }
}


export default TabView;